package com.eight.cloud.core.utils.structure.tree;

import com.eight.cloud.core.utils.structure.tree.annotation.Collect;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 数节点
 *
 * @ClassName: TreeNode
 * @Author: TXC
 * @Date: 2024-10-14 09:56
 **/

@Data
@NoArgsConstructor
@AllArgsConstructor
public class TreeNode<T> implements Serializable {
    /**
     * 数据id
     */
    private Object id;
    /**
     * 数据实体
     */
    private T data;
    /**
     * 直接子节点
     */
    private List<TreeNode<T>> childrenNode = new ArrayList<>();

    /**
     * 追溯父节点Id,有序，从0：root-》finally：parentId
     */
    private List<Object> parentNode = new ArrayList<>();

    /**
     * 同级节点Id
     */
    private List<Object> peerNode = new ArrayList<>();

    public TreeNode(T data, List<TreeNode<T>> childrenNode) {
        this.data = data;
        this.childrenNode = childrenNode;
    }
    /**
     * 获取子节点
     *
     * @param datas   数据集合
     * @param idName  id字段名
     * @param fidName fid字段名
     * @return 子节点集合
     */
    public List<TreeNode<T>> childrenNode(List<T> datas, String idName, String fidName, ConvertTree<T> convertTree) {
        List<T> collect = datas.stream()
                .filter(date -> this.id.equals(convertTree.getFieldValue(date, fidName)))
                .collect(Collectors.toList());
        // 获取所有节点id
        List<Object> childrenNodeId =
                collect.stream().map(m -> convertTree.getFieldValue(m, idName)).collect(Collectors.toList());
        datas.removeAll(collect);
        for (T node : collect) {
            TreeNode<T> treeNode = new TreeNode<>();
            convertTree.setId(treeNode, node, idName);
            convertTree.setData(treeNode, node);
            convertTree.setPeer(treeNode, childrenNodeId);
            convertTree.setParent(treeNode, initParent());
            childrenNode.add(treeNode);
        }
        return childrenNode;
    }

    public List<Object> initParent() {
        List<Object> copy = new ArrayList<>(parentNode);
        copy.add(id);
        return copy;
    }

    /**
     * 获取节点子节点Id
     *
     * @return id集合
     */
    public List<Object> obtainGetSubNode() {
        Object value = getFieldValue(data);
        List<Object> subNode = new ArrayList<>();
        subNode.add(value);
        recursionSetSubNode(subNode, this.getChildrenNode());
        return subNode;
    }

    public void recursionSetSubNode(List<Object> subNode, List<TreeNode<T>> nodeList) {
        nodeList.forEach(node -> {
            Object value = getFieldValue(node.getData());
            subNode.add(value);
            recursionSetSubNode(subNode, node.getChildrenNode());
        });
    }

    private Object getFieldValue(T data) {
        Class<?> clazz = data.getClass();
        // 得到所有属性
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(Collect.class)) {
                try {
                    field.setAccessible(true);
                    return field.get(data);
                } catch (IllegalAccessException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        return null;
    }
}
